package org.wx.io.netty.rpc.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;
import org.wx.io.netty.rpc.protocol.MyContent;
import org.wx.io.netty.rpc.protocol.MyHeader;
import org.wx.io.netty.rpc.protocol.PackMsg;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

/**
 * @description: prc的编码器
 * @author: wangxun
 * @createDate: 2021/2/23
 * @version: 1.0
 */
@Slf4j
public class RpcEncoder extends MessageToByteEncoder<PackMsg> {

    @Override
    protected void encode(ChannelHandlerContext ctx, PackMsg msg, ByteBuf out) throws Exception {


        // 得到内容对象字节数组
        byte[] contentBytes = getContentBytes(msg.getMyContent(), out);
        msg.getMyHeader().setDataLen(contentBytes.length);
        log.info("RpcEncode 调用，开始编码 PackMsg{}",msg);

        // 写出信息
        encodePackMsg(msg.getMyHeader(),out,contentBytes);


    }

    /**
     * 写出信息
     * @param myHeader
     * @param out
     */
    private void encodePackMsg(MyHeader myHeader, ByteBuf out,byte[] contentBytes) {

        out.writeInt(myHeader.getFlag());
        out.writeLong(myHeader.getRequestId());
        out.writeInt(contentBytes.length);
        out.writeBytes(contentBytes);
    }

    /**
     * 得到内容对象字节数组
     * @param myContent
     * @param out
     */
    private byte[] getContentBytes(MyContent myContent, ByteBuf out) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 将对象序列化到内存
        byte[] serialBytes = new byte[0];
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(myContent);
            // 获取序列化后的字节数组
            serialBytes = byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }



        return serialBytes;
    }
}
